package aiku.numericalcontroloa.Service.CompanyCulture.Impl;

import aiku.numericalcontroloa.Base.Utils.BaseEnum;
import aiku.numericalcontroloa.Base.Utils.HttpStatus;
import aiku.numericalcontroloa.Base.Utils.Result;
import aiku.numericalcontroloa.Mapper.MasterControl.MessageNotificationMapper;
import aiku.numericalcontroloa.Mapper.UserMapper;
import aiku.numericalcontroloa.Mapper.CompanyCulture.CommentMapper;
import aiku.numericalcontroloa.Mapper.CompanyCulture.LearnRecordMapper;
import aiku.numericalcontroloa.Mapper.CompanyCulture.MaterialMapper;
import aiku.numericalcontroloa.Model.Dto.CompanyCulture.MaterialDto;
import aiku.numericalcontroloa.Model.Entity.CompanyCulture.LearnRecord;
import aiku.numericalcontroloa.Model.Entity.MasterControl.MessageNotification;
import aiku.numericalcontroloa.Model.Entity.User;
import aiku.numericalcontroloa.Model.Entity.CompanyCulture.Comment;
import aiku.numericalcontroloa.Model.Entity.CompanyCulture.Material;
import aiku.numericalcontroloa.Model.Vo.CompanyCulture.MaterialVo;
import aiku.numericalcontroloa.Service.CompanyCulture.MaterialService;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Author 黄广庭
 * @Date 2024/1/8 14:58
 */
@Service
public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> implements MaterialService {
    private final UserMapper userMapper;
    private final MaterialMapper materialMapper;
    private final CommentMapper commentMapper;
    private final LearnRecordMapper learnRecordMapper;
    private final MessageNotificationMapper messageNotificationMapper;

    public MaterialServiceImpl(UserMapper userMapper, MaterialMapper materialMapper, CommentMapper commentMapper, LearnRecordMapper learnRecordMapper, MessageNotificationMapper messageNotificationMapper) {
        this.userMapper = userMapper;
        this.materialMapper = materialMapper;
        this.commentMapper = commentMapper;
        this.learnRecordMapper = learnRecordMapper;
        this.messageNotificationMapper = messageNotificationMapper;
    }

    @Override
    @Transactional
    public Result addMaterial(Material material) {
        if (material == null)
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        material.setUserId(StpUtil.getLoginId().toString());
        //System.out.println("material==>"+material);
        int insert = materialMapper.insert(material);
        // 类型为学习资料和培训视频时，给所有用户新增学习记录，和通知
        if (material.getType().equals(BaseEnum.MATERIAL_LEARN.getCodeInt())
                || Objects.equals(material.getType(), BaseEnum.MATERIAL_TRAIN.getCodeInt())){
            // 获取所有用户的id
            List<String> userIds = userMapper.selectAllId();
            List<LearnRecord> learnRecordList = new ArrayList<>();
            List<MessageNotification> messageNotificationList = new ArrayList<>();
            for (String userId : userIds) {
                // 创建学习记录
                LearnRecord learnRecord = new LearnRecord();
                learnRecord.setId(UUID.randomUUID().toString());
                learnRecord.setMaterialId(material.getId());
                learnRecord.setUserId(userId);
                learnRecordList.add(learnRecord);
                // 创建消息记录
                MessageNotification msg = new MessageNotification();
                msg.setId(UUID.randomUUID().toString().replaceAll("-",""));
                // 标题
                if (material.getType().equals(BaseEnum.MATERIAL_LEARN.getCodeInt())){
                    // 学习资料
                    msg.setTitle("有新的学习资料待学习");
                }else {
                    // 培训视频
                    msg.setTitle("有新的培训视频待观看");
                }
                // 内容为资料标题
                msg.setContent(material.getTitle());
                // 发布人为资料发布人
                msg.setPublisherId(material.getUserId());
                // 接收人为所有人
                msg.setReceiverId(userId);
                // 关联id为资料id
                msg.setRelevanceId(material.getId());
                // 类型为公司文化
                msg.setMsgType(1);
                // 子菜单为公司文化详情
                msg.setSubmenu(3);
                // 状态为待处理
                msg.setStatus(0);
                msg.setCreateTime(new Date());
                messageNotificationList.add(msg);
            }
            // 批量插入学习记录
            learnRecordMapper.insertBatch(learnRecordList);
            // 批量插入消息通知
            messageNotificationMapper.insertBatch(messageNotificationList);
        }
        if (insert > 0)
            return Result.success("添加成功");
        return Result.error("添加失败");
    }

    @Override
    public Result getMaterial(MaterialDto materialDto) {
        if (materialDto == null || materialDto.getId().isEmpty())
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        Material material = materialMapper.selectById(materialDto.getId());
        if (material == null){
            return new Result(HttpStatus.BAD_REQUEST,"该资料不存在");
        }
        MaterialVo materialVo = new MaterialVo();
        BeanUtils.copyProperties(material,materialVo);
        // 查询发布人
        User user = userMapper.selectByIdWithDelete(material.getUserId());
        materialVo.setNikeName(user.getNickName());
        // 处理日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        materialVo.setCreateTime(sdf.format(material.getCreateTime()));
        // 处理图片
        materialVo.setImageUrl(material.getImageUrl().split(";"));
        return Result.success("查询成功",materialVo);
    }

    @Override
    public Result getMaterialList(MaterialDto materialDto) {
        if (materialDto == null || (materialDto.getPageSize() == null
                && materialDto.getCurrentPage() == null))
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        Page<Material> page = new Page<>(materialDto.getCurrentPage(),materialDto.getPageSize());
        LambdaQueryWrapper<Material> materialWrapper = new LambdaQueryWrapper<>();
        materialWrapper.eq(Material::getDeleted,0).orderByDesc(Material::getCreateTime);

        // 模糊查询标题
        if (materialDto.getTitle() != null && !materialDto.getTitle().isEmpty()){
            materialWrapper.like(Material::getTitle,materialDto.getTitle());
        }
        // 按类型
        if (materialDto.getType() != null){
            materialWrapper.eq(Material::getType,materialDto.getType());
        }
        List<Material> materialList = materialMapper.selectPage(page, materialWrapper).getRecords();
        List<MaterialVo> materialVoList = new ArrayList<>();
        Map<String,Object> data = new HashMap<>();
        if (materialList.isEmpty()){
            data.put("total",page.getTotal());
            data.put("materialList",materialVoList);
            return Result.success("查询成功",data);
        }

        // 查发布人
        Set<String> userIdList = materialList.stream().map(Material::getUserId).collect(Collectors.toSet());
        List<User> userList = userMapper.selectBatchByIdWithDelete(userIdList);
        Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

        // 根据资料id和自己的id查学习记录
        List<String> materialIdList = materialList.stream().map(Material::getId).collect(Collectors.toList());
        LambdaQueryWrapper<LearnRecord> learnRecordLQW = new LambdaQueryWrapper<>();
        learnRecordLQW.eq(LearnRecord::getUserId,StpUtil.getLoginIdAsString())
                .in(LearnRecord::getMaterialId,materialIdList);
        List<LearnRecord> learnRecordList = learnRecordMapper.selectList(learnRecordLQW);
        // 根据materialId获取学习记录
        Map<String,LearnRecord> learnRecordMap = learnRecordList.stream().collect(Collectors.toMap(LearnRecord::getMaterialId,record ->learnRecordList.stream()
                .filter(learnRecord -> learnRecord.getMaterialId().equals(record.getMaterialId()))
                .findFirst()
                .orElse(null)));

        for (Material material : materialList){
            MaterialVo materialVo = new MaterialVo();
            BeanUtils.copyProperties(material,materialVo);
            // 查询发布人
            User user = userMap.get(material.getUserId());
            materialVo.setNikeName(user.getNickName());
            // 处理日期
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            materialVo.setCreateTime(sdf.format(material.getCreateTime()));
            // 处理图片
            if (material.getImageUrl() != null && !material.getImageUrl().isEmpty()){
                materialVo.setImageUrl(material.getImageUrl().split(";"));
            }
            // 处理内容
            if (material.getContent() != null && !material.getContent().isEmpty()){
                // 将标签全部删除
                Pattern HTML_TAG_PATTERN = Pattern.compile("<[^>]*>");
                Matcher matcher = HTML_TAG_PATTERN.matcher(material.getContent());
                materialVo.setContent(matcher.replaceAll(""));
            }
            // 学习状态，用于小程序端展示
            if (learnRecordMap.containsKey(material.getId())){
                LearnRecord learnRecord = learnRecordMap.get(material.getId());
                materialVo.setStatus(learnRecord.getStatus());
            }
            materialVoList.add(materialVo);
        }
        data.put("total",page.getTotal());
        data.put("materialList",materialVoList);
        return Result.success("查询成功",data);
    }

    @Override
    @Transactional
    public Result deleteMaterial(String id) {
        if(id == null || id.isEmpty())
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        int delete = materialMapper.deleteById(id);
        LambdaQueryWrapper<Comment> commentWrapper = new LambdaQueryWrapper<>();
        // 删除该资料的评论
        commentWrapper.eq(Comment::getMaterialId,id);
        commentMapper.delete(commentWrapper);
        // 删除该资料的学习记录
        LambdaQueryWrapper<LearnRecord> learnRecordWrapper = new LambdaQueryWrapper<>();
        learnRecordWrapper.eq(LearnRecord::getMaterialId,id);
        learnRecordMapper.delete(learnRecordWrapper);
        if (delete > 0)
            return Result.success("删除成功");
        return Result.error("删除失败");
    }

    @Override
    public Result addViewCount(Material materialDto) {
        if (materialDto == null){
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        }
        Material material = materialMapper.selectById(materialDto.getId());
        if (material == null){
            return new Result(HttpStatus.BAD_REQUEST,"该资料不存在");
        }
        Integer viewCount = material.getViewCount();
        viewCount++;
        // 给浏览量加1
        material.setViewCount(viewCount);
        // 更新数据
        materialMapper.updateById(material);
        return Result.success("修改成功");
    }
}
